package br.com.cong.dao.util;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.exception.JDBCExceptionHelper;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGenerationException;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.mapping.Table;
import org.hibernate.type.Type;
import org.hibernate.util.StringHelper;

public class NextNumberIdentifierGenerator implements IdentifierGenerator, Configurable {

	private long B;
	private String C;
	private Class A;

	public synchronized Serializable generate(SessionImplementor paramSessionImplementor, Object paramObject)
			throws HibernateException {
		A(paramSessionImplementor);
		return createNumber(this.B, this.A);
	}

	public static Number createNumber(long value, Class clazz) throws IdentifierGenerationException {
		if (clazz == Long.class) {
			return new Long(value);
		} else if (clazz == Integer.class) {
			return new Integer((int)value);
		} else if (clazz == Short.class) {
			return new Short((short)value);
		} else {
			throw new IdentifierGenerationException("this id generator generates long, integer, short");
		}
	}

	public void configure(Type paramType, Properties paramProperties, Dialect paramDialect) throws MappingException {
		String str1 = paramProperties.getProperty("tables");
		if (str1 == null)
			str1 = paramProperties.getProperty("identity_tables");
		String[] arrayOfString = StringHelper.split(", ", str1);
		String str2 = paramProperties.getProperty("column");
		if (str2 == null)
			str2 = paramProperties.getProperty("target_column");
		String str3 = paramProperties.getProperty("schema");
		String str4 = paramProperties.getProperty("catalog");
		this.A = paramType.getReturnedClass();
		StringBuffer localStringBuffer = new StringBuffer();
		for (int i = 0; i < arrayOfString.length; i++) {
			if (arrayOfString.length > 1)
				localStringBuffer.append("select ").append(str2).append(" from ");
			localStringBuffer.append(Table.qualify(str4, str3, arrayOfString[i]));
			if (i >= arrayOfString.length - 1)
				continue;
			localStringBuffer.append(" union ");
		}
		if (arrayOfString.length > 1) {
			localStringBuffer.insert(0, "( ").append(" ) ids_");
			str2 = "ids_." + str2;
		}
		this.C = ("select max(" + str2 + ") from " + localStringBuffer.toString());
	}

	private void A(SessionImplementor paramSessionImplementor) {
		long l;
		try {
			PreparedStatement localPreparedStatement =
					paramSessionImplementor.getBatcher().prepareSelectStatement(this.C);
			try {
				ResultSet localResultSet = localPreparedStatement.executeQuery();
				try {
					if (localResultSet.next()) {
						l = localResultSet.getLong(1) + 1L;
						if (localResultSet.wasNull())
							l = 1L;
					} else {
						l = 1L;
					}
				} finally {
					localResultSet.close();
				}
			} finally {
				paramSessionImplementor.getBatcher().closeStatement(localPreparedStatement);
			}
		} catch (SQLException localSQLException) {
			throw JDBCExceptionHelper.convert(paramSessionImplementor.getFactory().getSQLExceptionConverter(),
					localSQLException, "could not fetch initial value for increment generator", this.C);
		}
		if (this.B < l)
			this.B = l;
		else
			this.B += 1L;
	}
}